from django.db import transaction
from rest_framework import serializers
from goods.models import SKU, SpecificationOption, SKUSpecification
from goods.models import GoodsCategory
from goods.models import SPU, SPUSpecification


#0,SKUSpecification序列化器
class SKUSpecificationSerializer(serializers.Serializer):
    # 让规格知道入哪个库
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()




# 商品视图序列化器
class SKUViewSetserializer(serializers.ModelSerializer):
    # 重写分类,让表显示中文
    category = serializers.StringRelatedField(read_only=True)
    category_id = serializers.IntegerField()

    # 2,spu重写
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()

    # 3,specs重写
    specs = SKUSpecificationSerializer(read_only=True, many=True)

    class Meta:
        model = SKU
        fields = "__all__"

    # 系统的方法只保存商品,没保存到规格,重写保存商品对应的规格
    @transaction.atomic
    def create(self, validated_data):
        # 设置保存点
        sid = transaction.savepoint()
        try:
            # 商品普通信息入库
            sku = SKU.objects.create(**validated_data)

            # 获取规格信息
            specs = self.context["request"].data["specs"]

            for spec_dict in specs:
                SKUSpecification.objects.create(sku_id=sku.id, spec_id=spec_dict["spec_id"],
                                            option_id=spec_dict["option_id"])
        except Exception as e:
            transaction.savepoint_rollback(sid)  # 回滚
            raise serializers.ValidationError("保存失败")
        else:
            transaction.savepoint_commit(sid)  # 提交
            return sku

    # 重写update

    @transaction.atomic
    def update(self, instance, validated_data):
        # 设置保存点
        sid = transaction.savepoint()

        try:
            # 更新sku其他信息(标题, 价格, ...)
            SKU.objects.filter(id=instance.id).update(**validated_data)

            # 更新规格
            specs = self.context["request"].data["specs"]
            for spec_dict in specs:
                SKUSpecification.objects.create(sku_id=instance.id, spec_id=spec_dict["spec_id"],
                                                option_id=spec_dict["option_id"])
        except Exception as e:
            transaction.savepoint_rollback(sid)
            raise serializers.ValidationError("保存失败")
        else:
            transaction.savepoint_commit(sid)
            return SKU.objects.filter(id=instance.id)


# 商品三级分类序列化器
class GoodsCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = ("id", "name")


# 商品简要信息序列化器
class SPUSerializer(serializers.ModelSerializer):
    class Meta:
        model = SPU
        fields = ("id", "name")



# 商品规格的选项
class SpecificationOptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = SpecificationOption
        fields = ("id", "value")


# 商品规格序列化器
class SPUSpecificationSerializer(serializers.ModelSerializer):
    # 1,重写spu类, 为的是让系统知道新加的商品加入哪一个类
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()

    # 2,重写option, 一对多,序列化一,多方的外键没有被动到,因此渲染不出来,因此要重写
    options = SpecificationOptionSerializer(read_only=True, many=True)

    class Meta:
        model = SPUSpecification
        fields = "__all__"



